/*
 * Copyright 2009 Gary Brown
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *
 * Change History:
 * 7 Mar 2009 : Initial version created by gary
 */
package org.betonthemove.ui.android;

import org.betonthemove.platform.BettingPlatform;
import org.betonthemove.platform.BettingPlatformFactory;
import org.betonthemove.platform.Market;
import org.betonthemove.platform.MarketGroup;

import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;

public class MarketSelection extends ListActivity
							implements Runnable {

	//private static final int MAX_MARKET_ENTRANTS = 500;
	private static final String SEVENDAYS_PREF_VALUE = "sevendays";
	private static final String THREEDAYS_PREF_VALUE = "threedays";
	private static final String TODAY_PREF_VALUE = "today";
	private static final String TIME_RANGE_PREFERENCE = "time_range";
	private static final String GBR_PREF_VALUE = "GBR";
	private static final String UNLIMITED_PREF_VALUE = "unlimited";
	private static final String COUNTRIES_PREFERENCE = "countries";
	public static final String MARKET_GROUP_ATTR = "org.betonthemove.MarketGroup";

	private static final int WAITING_DIALOG = 1;
    private static final int ERROR_DIALOG = 2;
    private static final int ERROR_MESSAGE_DISPLAY_DELAY = 4000;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

		m_eventTypeId = getIntent().getIntExtra(EventTypeSelection.EVENT_TYPE_ID_ATTR, -1);
		m_marketGroup = (MarketGroup)
				getIntent().getSerializableExtra(MARKET_GROUP_ATTR);
		
        java.util.List<String> list=new java.util.Vector<String>();
        
        setListAdapter(new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, list));
        getListView().setTextFilterEnabled(true);
        
		if (m_marketGroup != null) {
    		BettingPlatform platform=BettingPlatformFactory.getBettingPlatform();

    		try {
	    		m_subGroups=platform.getSubGroups(m_marketGroup);
	    		
				for (int i=0; m_subGroups != null &&
							i < m_subGroups.size(); i++) {
					list.add(m_subGroups.get(i).getName()+" ...");
				}
				
	    		m_markets=platform.getMarkets(m_marketGroup);
    		
				for (int i=0; i < m_markets.size(); i++) {
					String text=m_markets.get(i).getMarketName();
					
					if (m_eventTypeId == 7) {
						// Horse racing
						java.util.Date d=new java.util.Date(m_markets.get(i).getStartDate());
						
						String mins=""+d.getMinutes();
						if (d.getMinutes() < 10) {
							mins = "0"+mins;
						}
						
						text += " ("+d.getHours()+":"+mins+")";
					}
					
					list.add(text);
				}
    		} catch(Exception e) {
        		m_error = "ERROR: "+e.getLocalizedMessage();
        		m_state = 5;
    		}
		} else {
			runOnUiThread(this);
		}
    }

    protected void onListItemClick(ListView l, View v, int position, long id) {
        Intent intent = new Intent();
        
        if (m_subGroups == null || position >= m_subGroups.size()) {
        	intent.setClass(MarketSelection.this, MarketView.class);
        
        	if (m_subGroups != null) {
        		position -= m_subGroups.size();
        	}
        	
        	Market market=m_markets.get(position);
        	
           	intent.putExtra(MarketView.MARKET_ID_ATTR,
        			market.getMarketId());
            
           	intent.putExtra(EventTypeSelection.EVENT_TYPE_ID_ATTR,
        			m_eventTypeId);
            
        	intent.putExtra(MarketView.MARKET_NAME_ATTR,
        			market.getMarketName());
        	
        	String category=market.getMenuPath();
        	int index=category.lastIndexOf('\\');
        	
        	if (index != -1) {
        		category = category.substring(index+1);
        	}
        	
        	intent.putExtra(MarketView.MARKET_CATEGORY_ATTR,
        			category);
        	
        	intent.putExtra(MarketView.MARKET_START_DATE_ATTR,
        			market.getStartDate());
            
        	intent.putExtra(MarketView.MARKET_DUE_IN_PLAY_ATTR,
        			market.isDueInPlay());
        } else {
        	intent.setClass(MarketSelection.this, MarketSelection.class);
        	
           	intent.putExtra(EventTypeSelection.EVENT_TYPE_ID_ATTR,
        			m_eventTypeId);

           	intent.putExtra(MarketSelection.MARKET_GROUP_ATTR,
        				m_subGroups.get(position));
        }
        
        startActivity(intent);
	}
    
    public void run() {
    	
    	if (m_state == 0) {
    		showDialog(WAITING_DIALOG);
    		
    		m_state++;
    		
    		new Thread(this).start();
    	} else if (m_state == 1) {

    		BettingPlatform platform=BettingPlatformFactory.getBettingPlatform();
        
	        try {
	        	int days=getDaysLookahead();
	        	java.util.List<String> countries=getCountries();
	        	
		        m_marketGroup=platform.getMarkets(m_eventTypeId, days,
		        					countries);
		        
		        if (m_marketGroup != null) {
		    		m_subGroups=platform.getSubGroups(m_marketGroup);
		    		m_markets=platform.getMarkets(m_marketGroup);
		        	
		    		/* May need to restrict size of compressed
		    		 * prices that can be processed
		    		 * 
		        	if (m_marketGroup.getMarketCount() > MAX_MARKET_ENTRANTS) {
		        		throw new BettingException("Too many markets. You need to adjust preferences " +
		        				"to reduce number of markets returned");
		        	}
		        	*/
		        }
		        
		        m_state++;
		        
	        } catch(Throwable e) {
	        	
	        	if (e instanceof java.lang.OutOfMemoryError) {
	        		m_error = "ERROR: "+
	        			"Too many markets. You need to adjust preferences " +
        				"to reduce number of markets returned";
	        	} else {
	        		m_error = "ERROR: "+e.getLocalizedMessage();
	        	}
	        	
	        	m_state = 5;
	        }

	        runOnUiThread(this);
    	} else if (m_state == 2) {    		
			if (m_marketGroup != null) {
				for (int i=0; m_subGroups != null &&
								i < m_subGroups.size(); i++) {
					((ArrayAdapter<String>)getListAdapter()).add(m_subGroups.get(i).getName()+" ...");
				}
				for (int i=0; m_markets != null &&
								i < m_markets.size(); i++) {
					String text=m_markets.get(i).getMarketName();
					
					if (m_eventTypeId == 7) {
						// Horse racing
						java.util.Date d=new java.util.Date(m_markets.get(i).getStartDate());
						
						String mins=""+d.getMinutes();
						if (d.getMinutes() < 10) {
							mins = "0"+mins;
						}
						
						text += " ("+d.getHours()+":"+mins+")";
					}
					
					((ArrayAdapter<String>)getListAdapter()).add(text);
				}
				
		        dismissDialog(WAITING_DIALOG);
			} else {
				m_error = "No markets currently available "+
							"for this event type";
				
				m_state = 5;
				
				runOnUiThread(this);
			}

    	} else if (m_state == 5) {

    		dismissDialog(WAITING_DIALOG);
	        
	        showDialog(ERROR_DIALOG);
	        
	        m_state++;
	        
	        new Thread(this).start();
	        
    	} else if (m_state == 6) {

    		try {
    			synchronized(this) {
    				wait(ERROR_MESSAGE_DISPLAY_DELAY);
    			}
    		} catch(Exception e) {
    			e.printStackTrace();
    		}
    		
    		m_state++;
    		
    		runOnUiThread(this);
    		
    	} else if (m_state == 7) {
    		
    		dismissDialog(ERROR_DIALOG);
    		
    		m_error = null;
    		
    		if (m_marketGroup == null) {
    			finish();
    		} else {
    			// Go back to refresh state
    			m_state = 2;
    			
        		runOnUiThread(this);
    		}
    	}
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case WAITING_DIALOG: {
                ProgressDialog dialog = new ProgressDialog(this);
                dialog.setMessage("Retrieving markets...");
                dialog.setIndeterminate(true);
                dialog.setCancelable(true);
                return dialog;
            }
            case ERROR_DIALOG: {
                ProgressDialog dialog = new ProgressDialog(this);
                dialog.setMessage(m_error);
                dialog.setIndeterminate(true);
                dialog.setCancelable(true);
                return dialog;
            }
        }
        return null;
    }
  
	/* Creates the menu items */
	public boolean onCreateOptionsMenu(Menu menu) {
	    return(OptionsMenuSupport.onCreateOptionsMenu(menu));
	}

	/* Handles item selections */
	public boolean onOptionsItemSelected(MenuItem item) {
	    return(OptionsMenuSupport.onOptionsItemSelected(MarketSelection.this, item));
	}

	public int getDaysLookahead() {
		int ret=7;
		
		SharedPreferences prefs=PreferenceManager.getDefaultSharedPreferences(this);
		
		if (prefs != null) {
			String timeRange=prefs.getString(TIME_RANGE_PREFERENCE, SEVENDAYS_PREF_VALUE);
	
			if (timeRange.equals(TODAY_PREF_VALUE)) {
				ret = 1;
			} else if (timeRange.equals(THREEDAYS_PREF_VALUE)) {
				ret = 3;
			} else if (timeRange.equals(SEVENDAYS_PREF_VALUE)) {
				ret = 7;
			} else if (timeRange.equals(UNLIMITED_PREF_VALUE)) {
				ret = 0;
			}
		}
		
		return(ret);
	}
	
	public java.util.List<String> getCountries() {
		java.util.List<String> ret=new java.util.Vector<String>();
		
		SharedPreferences prefs=PreferenceManager.getDefaultSharedPreferences(this);
		
		if (prefs != null) {
			String countries=prefs.getString(COUNTRIES_PREFERENCE, GBR_PREF_VALUE);
			
			if (countries.equals(GBR_PREF_VALUE)) {
				ret.add(countries);
			} else if (countries.equals(UNLIMITED_PREF_VALUE)) {
				// Return empty list
			}
		}
	
		return(ret);
	}
	
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);		
	}

	private int m_state=0;
    private int m_eventTypeId=0;
    private MarketGroup m_marketGroup=null;
    private java.util.List<MarketGroup> m_subGroups=null;
    private java.util.List<Market> m_markets=null;
	private String m_error=null;
}